package com.kang.c0c.parser;

import com.kang.c0c.symbol.ConstantSymbol;
import com.kang.c0c.symbol.FunctionSymbol;
import com.kang.c0c.symbol.Kinds;
import com.kang.c0c.symbol.NameTable;
import com.kang.c0c.symbol.Symbol;
import com.kang.c0c.symbol.GlobalTable;
import com.kang.c0c.symbol.Type;
import com.kang.c0c.tree.Tree;
import com.kang.c0c.tree.node.BinaryNode;
import com.kang.c0c.tree.node.BlockNode;
import com.kang.c0c.tree.node.CallNode;
import com.kang.c0c.tree.node.EvaluateNode;
import com.kang.c0c.tree.node.FunctionNode;
import com.kang.c0c.tree.node.IfNode;
import com.kang.c0c.tree.node.LeafNode;
import com.kang.c0c.tree.node.Node;
import com.kang.c0c.tree.node.Nodes;
import com.kang.c0c.tree.node.PrintNode;
import com.kang.c0c.tree.node.ReturnNode;
import com.kang.c0c.tree.node.ScanNode;
import com.kang.c0c.tree.node.WhileNode;
import com.kang.c0c.util.Context;
import com.kang.c0c.util.Log;
import com.kang.c0c.util.PString;

/**
 * 语法分析器生成抽象语法树并进行小的语义分析
 * 符号表由com.kang.c0c.symbol中的各个类管理
 * 抽象语法树的数据结构则由com.kang.c0c.tree（以及其下属包node)实现
 * 抽象语法树的构造则由语法分析器各个涉及到语法树的节点的递归下降子程序来负责
 * 
 * 递归下降子程序的入口在Program()
 * 
 * 递归下降子程序采用的是“一步一步把关”递归下降子程序，也就是普通的if(if(...)else(...))else(...)类型的if嵌套
 * 在ReadStatement()、PrintStatement()、ReturnStatement()中采用了“拒绝就走人”的方法
 * 打比方说，对于规则	A	::=	( B + C )
 * 一步一步把关 法为：
 * procedure A(){
 * 	if(token == '('){
 * 		nextToken();
 * 		B();
 * 
 * 		if(token ==	'+'){
 * 			nextToken();
 * 			C();
 * 
 * 			if(token == ')')
 * 				nextToken();
 * 			else error();
 * 
 * 		}else error();
 * 		
 * 	}else error();
 * }
 * 拒绝就走人	法为：
 * procedure A(){
 * 	if(token == '(')
 * 		nextToken();
 * 	else{
 * 		error();
 * 		return ;
 * 	}
 * 
 * 	B();
 * 	
 * 	if(token == '+')
 * 		nextToken();
 * 	else{
 * 		error();
 * 		return;
 * 	}
 * 
 * 	C();
 * 
 * 	if(token == ')')
 * 		nextToken();
 * 	else
 * 		error();
 * }
 * 
 * “拒绝就走人”的好处是避免了“一步一步把关”里面的if...else...的不断嵌套，使得用文法检查代码时更为方便一些
 * 
 * @author kang
 *
 * Feb 8, 2009
 */
public class Parser implements Tokens,Kinds{
	
	public Parser(Context context){
		super();
		
		log = Log.instance(context);
		globalTable = GlobalTable.instance(context);
		tree = Tree.instance(context);
		scanner = new Scanner(context);
		token = scanner.nextToken();
	}
	
	/**
	 * 语法错误报错子函数，并抑制在同一处重复报错
	 * 
	 * @param pos			：出错位置
	 * @param msg			：出错信息
	 */
	private void syntaxError(int pos,String msg){
		if(pos != scanner.errPos){
			log.error(pos, "Syntax error : " + msg);
			scanner.errPos = pos;
		}
	}
	
	private void Error(int pos,String msg){
		if(pos != scanner.errPos){
			log.error(pos, msg);
			scanner.errPos = pos;
		}
	}
	
	/**
	 * 跳过一些记号直至到达了默认的一些c0文法中常出现的记号
	 * skip()、skipTo()、skipToSEMI()基本相同，主要功能类似
	 * 它们是错误处理跳过出错位置的语句或程序块时使用，不过有一个大的遗漏点就是不能判断读到的标识符是否为关键字int,void的拼写错误
	 */
	private void skip() {
        int nbraces = 0;
        int nparens = 0;
        while (true) {
			switch (token.getToken()) {
			case EOF:
			case INT:
			case VOID:
				return;
			case SEMI:
				if (nbraces == 0 && nparens == 0)
					return;
				break;
			case RBRACKET:
				if (nbraces == 0)
					return;
				nbraces--;
				break;
			case RPAREN:
				if (nparens > 0)
					nparens--;
				break;
			case LBRACKET:
				nbraces++;
				break;
			case LPAREN:
				nparens++;
				break;
			default:
				break;
			}
        	
            token = scanner.nextToken();
        }
    }
	
	/**
	 * 跳过一些记号直至到达了默认的一些c0文法中常出现的记号或者是某一个用户希望到达的记号dest
	 * 
	 * @param dest
	 */
	private void skipTo(int dest){
		 int nbraces = 0;
	     int nparens = 0;
	     
	     while(true){
	    	 if(token.getToken() == dest){
	    		 if(nbraces==0 && nparens==0)
	    			 return;
	    	 }
	    	 
	    	 switch (token.getToken()) {
				case EOF:
				case INT:
				case VOID:
					return;
				case SEMI:
					if (nbraces == 0 && nparens == 0)
						return;
					break;
				case RBRACKET:
					if (nbraces == 0)
						return;
					nbraces--;
					break;
				case RPAREN:
					if (nparens > 0)
						nparens--;
					break;
				case LBRACKET:
					nbraces++;
					break;
				case LPAREN:
					nparens++;
					break;
				default:
					break;
				}
	    	 
	    	 token = scanner.nextToken();
	     }
	}
	
	/**
	 * 调过某一个语句或者程序块，并到达下一句或者下一个程序块的起始位置
	 */
	private void skipToSEMI(){
		skip();
		
		if((token.getToken() == SEMI)
				||(token.getToken() == RBRACKET))
			token = scanner.nextToken();
	}
	
	/**
	 * 根据给定的符号表和标识符记号，查找记号是否是符号表内的一项信息
	 * 
	 * @param ident			：需要检验的标识符记号
	 * @param nameTable		：给定的符号表
	 * @return 				：返回查找结果（查找结果为NULL时表示此符号表中没有此标识符）
	 */
	private Symbol lookup(Token ident, NameTable nameTable){
		Symbol sym = nameTable.get((String)ident.getValue());
		
		NameTable table = nameTable;
		while((sym == null)&&(table.getFather() != null)){
			table = table.getFather();
			sym = table.get((String)ident.getValue());
		}
		
		if(sym == null)
			Error(ident.getPos(), "Undefined identifier '" + ident.getValue() + "'");
		
		return sym;
	}
	
	/**
	 * Program				::=  ［ConstantDec］［VarDec］｛FuncDef｝MainDef
	 * ConstantDec			::=  const ConstantDef｛,ConstantDef｝';'
	 * ConstantDef			::=   Identifier'＝'Integer
	 * DecHead				::=  int　Identifier
	 * VarDec				::=  DecHead｛，Identifier｝';'
	 * FuncDef				::=  （DecHead｜void Identifier）Parameter Block
	 * Parameter			::= ‘(’ParamList‘)’
	 * MainDef				::=   void main‘(’‘)’Block
	 * 
	 * 
	 * 函数进入时token值		：整个语法分析器进行语法分析的入口
	 * 函数退出时token值		：函数退出时语法分析结束
	 */
	public void Program(){
		if(token.getToken() == Tokens.CONST){
			Constant(globalTable.nameTable);
		}else if(token.getToken() == IDENTIFIER){
			/*
			 * 在没有遇到以const为开头时，且当前记号为用户自定义标识符，则判断是否为用户拼错了关键字所致，并进行恰当的恢复
			 * 否则将直接过滤掉这个记号，读取下一个记号，重新进行Program()
			 */
			if(PString.liksKeywords((String)token.getValue(), "const")){
				token = new Token(Tokens.CONST,null,token.getPos());
				Error(token.getPos(), "The keyword 'const' is not correctly spelled");
				Program();
				
				return;
			}else{
				syntaxError(token.getPos(),scanner.dumpToken(token));
				skipTo(Tokens.CONST);
				if(token.getToken() == SEMI
						|| token.getToken() == RBRACKET)
					token = scanner.nextToken();
				
				Program();
				
				return;
			}
		}
		
		if(token.getToken() == INT){
			DecHead();
		}else if(token.getToken() == VOID){
			voidFunc();
		}else if(token.getToken() == EOF){
			return;
		}else{
			syntaxError(token.getPos(),scanner.dumpToken(token));
			/*
			 * 在没有遇到int,void为开头时，且当前记号为用户自定义标识符，则判断是否为用户拼错了关键字所致，并进行恰当的恢复
			 * 否则将直接过滤掉这个记号，读取下一个记号，重新进行Program()
			 */
			if(token.getToken() == IDENTIFIER){
				if(PString.liksKeywords((String)token.getValue(), "int")){
					token = new Token(INT,null,token.getPos());
					Error(token.getPos(), "The keyword 'int' is not correctly spelled");
				}else if(PString.liksKeywords((String)token.getValue(), "void")){
					token = new Token(VOID,null,token.getPos());
					Error(token.getPos(), "The keyword 'const' is not correctly spelled");
				}
			}else{
				Error(token.getPos(), "No usage start with this token: " + scanner.dumpToken(token) );
				skip();
				if(token.getToken() == SEMI
						|| token.getToken() == RBRACKET)
					token = scanner.nextToken();
			}
			
			Program();
		}
	}

	/**
	 * ConstantDec			::=  const ConstantDef｛,ConstantDef｝';'
	 * ConstantDef			::=   Identifier'＝'Integer
	 * 
	 * 函数进入时token值		：CONST
	 * 函数退出时token值		：SEMI的下一个记号
	 * 
	 * @param table			指明了分析得到的变量标识符应该插入哪个符号表中，这主要是区分这个变量分析是局部的还是哪个函数内部的
	 */
	private void Constant(NameTable table){
		/*
		 * 错误处理方法将同步符号定位在‘，’上
		 */
		do{
			token = scanner.nextToken();
			
			if(token.getToken() == IDENTIFIER){
				Token ident = token;
				token = scanner.nextToken();
			
				if(token.getToken() == EQ){
					token = scanner.nextToken();
					
					boolean neg = false;
					if(token.getToken() == SUB){
						neg = true;
						token = scanner.nextToken();
					}
					
					if(token.getToken() == NUM){
						if(neg){
							int number= (Integer)token.getValue();
							token = new Token(NUM,-number,token.getPos());
						}
						NameTable.insertConst(table, ident, token, log);
						token = scanner.nextToken();
					}else{
						log.error(token.getPos(), "'const' synax: A number is required! Unkonwed " + scanner.dumpToken(token));
						skipTo(COMMA);
					}
					
				}else{
					log.error(token.getPos(), "'const' synax:" + scanner.dumpToken(token));
					skipTo(COMMA);
						
				}
				
			}else{
				if(token.getToken() == EQ){
					log.error(token.getPos(), "'const' syntax: No variable declared before '='");
				}
				else{
					log.error(token.getPos(), "'const'");
				}
				skipTo(COMMA);
			}
			
		}while(token.getToken() == COMMA);
		
		if(token.getToken() == SEMI){
			token = scanner.nextToken();
		}else{
			syntaxError(token.getPos(),"Missing ';' before " + scanner.dumpToken(token));
			skip();
			
			if((token.getToken() == SEMI)
					||(token.getToken() == RBRACKET))
				token = scanner.nextToken();
		}		
	}

	/**
	 * DecHead				::=  int　Identifier
	 * VarDec				::=  DecHead｛，Identifier｝';'
	 * FuncDef				::=  （DecHead｜void Identifier）Parameter Block
	 * 
	 * 函数进入时token值		：INT
	 * 函数退出时token值		：函数退出时语法分析结束
	 * 
	 * 主要目的是为了在此处判断是VarDec还是FuncDef，它并不负责用户自定义函数内部的VarDec里的DecHead
	 * DecHead()只负责全局的DecHead的判定，至于用户自定义的函数其内部的DecHead则由其它相应的函数来处理
	 */
	private void DecHead(){
		token = scanner.nextToken();
		
		if(token.getToken() == IDENTIFIER){
			Token ident = token;
			token = scanner.nextToken();
		
			if(token.getToken() == COMMA){
				NameTable.insertVar(globalTable.nameTable, ident , log);
				SubVarDec(globalTable.nameTable);
			}else if(token.getToken() == LPAREN){
				FunctionSymbol funcSym = NameTable.insertFunc(globalTable.nameTable, ident, Type.INT, log);
				FunctionNode funcNode = tree.insertFunction(funcSym);
				
				Parameter(funcSym);
				Block(funcSym.nameTable, funcNode.getBlock());
			}else if(token.getToken() == SEMI){
				NameTable.insertVar(globalTable.nameTable, ident , log);
				token = scanner.nextToken();
			}else{
				syntaxError(token.getPos(), "Which kind of identifier (variable or function) do you want to declare with " 
						+ scanner.dumpToken(token) + "?");
				
				//跳到函数程序块处或者下一个函数申明处
				while((token.getToken() == SEMI)
						||(token.getToken() == RBRACKET)){
					token = scanner.nextToken();
					skip();
				}
				
			}
			
			
		}else{
			syntaxError(token.getPos(), "An identifier is required to declare a variable or function, not " + scanner.dumpToken(token));
			
			//跳到函数程序块处或者下一个函数申明处
			while((token.getToken() == SEMI)
					||(token.getToken() == RBRACKET)){
				token = scanner.nextToken();
				skip();
			}
		}
		
		FuncHead();
	}
	
	/**
	 * VarDec				::=  DecHead SubVarDec
	 * SubVarDec			::=  ｛，Identifier｝';'
	 * 
	 * 函数进入时token值		：COMMA或者SEMI
	 * 函数退出时token值		：SEMI的下一个记号
	 * 
	 * @param table			指明了分析得到的变量标识符应该插入哪个符号表中，这主要是区分这个变量分析是局部的还是哪个函数内部的
	 */
	private void SubVarDec(NameTable table){
		while(token.getToken() == COMMA){
			token = scanner.nextToken();
			
			if(token.getToken() == IDENTIFIER){
				NameTable.insertVar(table, token, log);
				token = scanner.nextToken();
			}else{
				syntaxError(token.getPos(), "Wrong way to declare a variable with " + scanner.dumpToken(token));
				skipTo(COMMA);
			}
		}
		
		if(token.getToken() == SEMI){
			token = scanner.nextToken();
		}else{
			syntaxError(token.getPos(),"Missing ';' before " + scanner.dumpToken(token));
			skip();
			
			if((token.getToken() == SEMI)
					||(token.getToken() == RBRACKET))
				token = scanner.nextToken();
		}
	}
	
	/**
	 * DecHead				::=  int　Identifier
	 * VarDec				::=  DecHead SubVarDec
	 * SubVarDec			::=  ｛，Identifier｝';'
	 * 
	 * 函数进入时token值		：INT
	 * 函数退出时token值		：SubVarDec()退出时的token值<SEMI的下一个记号>
	 * 
	 *@param table			指明了分析得到的变量标识符应该插入哪个符号表中，这主要是区分这个变量分析是局部的还是哪个函数内部的
	 */
	private void VarDec(NameTable table){
		token = scanner.nextToken();
			
		if(token.getToken() == IDENTIFIER){
			NameTable.insertVar(table, token, log);
			token = scanner.nextToken();
			SubVarDec(table);
		}else{
			syntaxError(token.getPos(), "Wrong way to declare a variable with " + scanner.dumpToken(token));
			skipTo(COMMA);
			
			if(token.getToken() == COMMA)
				SubVarDec(table);
			else if(token.getToken() == SEMI)
				token = scanner.nextToken();
			else{
				syntaxError(token.getPos(),"Missing ';' before " + scanner.dumpToken(token));
				if(token.getToken() == RBRACKET)
					token = scanner.nextToken();
			}
		}
	}
	
	/**
	 * FuncDef				::=  （DecHead｜void Identifier）Parameter Block
	 * Parameter			::= ‘(’ParamList‘)’
	 * 
	 * 函数进入时token值		：函数申明的开头(INT、VOID)或者是程序记号流的结束(EOF)
	 * 函数退出时token值		：intFunc()、voidFunc()、FuncHead()递归调用完成源程序中所有函数申明定义的处理
	 */
	private void FuncHead(){
		if(token.getToken() == INT){
			intFunc();
		}else if(token.getToken() == VOID){
			voidFunc();
		}else if(token.getToken() == EOF){
			return;
		}else{
			syntaxError(token.getPos(),scanner.dumpToken(token));
			
			/*
			 * 在没有遇到int,void为开头时，且当前记号为用户自定义标识符，则判断是否为用户拼错了关键字所致，并进行恰当的恢复
			 * 否则将直接过滤掉这个记号，读取下一个记号，重新进行FuncHead()
			 */
			if(token.getToken() == IDENTIFIER){
				if(PString.liksKeywords((String)token.getValue(), "int")){
					token = new Token(INT,null,token.getPos());
					Error(token.getPos(), "The keyword 'int' is not correctly spelled");
				}else if(PString.liksKeywords((String)token.getValue(), "void")){
					token = new Token(VOID,null,token.getPos());
					Error(token.getPos(), "The keyword 'const' is not correctly spelled");
				}
			}else{
				syntaxError(token.getPos(),"No usage with " + scanner.dumpToken(token));
				skip();
				
				while((token.getToken() == SEMI)
						|| (token.getToken() == RBRACKET)){
					token = scanner.nextToken();
					skip();
				}
			}
			
			FuncHead();
		}
	}
	
	/**
	 * intFunc				::=  DecHead Parameter Block
	 * DecHead				::=  int　Identifier
	 * 
	 * 函数进入时token值		：INT
	 * 函数退出时token值		：intFunc()与FuncHead()递归调用，
	 * 						  必须保证Parameter()、Block()、FuncHead()的记号流连续
	 */
	private void intFunc(){
		token = scanner.nextToken();
		
		if(token.getToken() == IDENTIFIER){
			FunctionSymbol funcSym = NameTable.insertFunc(globalTable.nameTable, token, Type.INT, log);
			FunctionNode funcNode = tree.insertFunction(funcSym);
			
			token = scanner.nextToken();
			Parameter(funcSym);
			Block(funcSym.nameTable, funcNode.getBlock());
			FuncHead();
		}else{
			syntaxError(token.getPos(), "Wrong way to declare a function with " + scanner.dumpToken(token));

			skip();
			//跳到函数程序块处或者下一个函数申明处
			while((token.getToken() == SEMI)
					||(token.getToken() == RBRACKET)){
				token = scanner.nextToken();
				skip();
			}
			FuncHead();
		}
	}
	
	/**
	 * voidFunc				::=	void Identifier Parameter Block
	 * MainDef				::=	void main'('')'Block
	 * 
	 * 函数进入时token值		：VOID
	 * 函数退出时token值		：voidFunc()与FuncHead()递归调用，
	 * 						  必须保证Parameter()、Block()、FuncHead()的记号流连续
	 */
	private void voidFunc(){
		token = scanner.nextToken();//读取下一个记号取代已知的VOID
		
		if(token.getToken() == MAIN){
			MainDef();
		}else if(token.getToken() == IDENTIFIER){
			FunctionSymbol funcSym = NameTable.insertFunc(globalTable.nameTable, token, Type.VOID, log);
			FunctionNode funcNode = tree.insertFunction(funcSym);
			
			token = scanner.nextToken();
			Parameter(funcSym);
			Block(funcSym.nameTable, funcNode.getBlock());
			FuncHead();
		}else{
			syntaxError(token.getPos(), "Wrong way to declare a function with " + scanner.dumpToken(token));

			//跳到函数程序块处或者下一个函数申明处
			while((token.getToken() == SEMI)
					||(token.getToken() == RBRACKET)){
				token = scanner.nextToken();
				skip();
			}
			FuncHead();
		}
	}
	
	/**
	 * MainDef				::=   void main‘（’‘)’Block
	 * 
	 * 函数进入时token值		：MAIN
	 * 函数退出时token值		：Block()函数退出时的token值，函数退出时语法分析结束
	 */
	private void MainDef(){
		token = new Token(token.getToken(),"main",token.getPos());
		
		FunctionSymbol funcSym = NameTable.insertFunc(globalTable.nameTable, token, Type.VOID, log);
		FunctionNode funcNode = tree.insertFunction(funcSym);
		
		token = scanner.nextToken();
		
		if(token.getToken() == LPAREN){
			token = scanner.nextToken();
		
			if(token.getToken() == RPAREN){
				token = scanner.nextToken();
				Block(funcSym.nameTable, funcNode.getBlock());
				
				//main()函数后应该是程序结束
				if(token.getToken() == EOF)
					return;
				syntaxError(token.getPos(), "The main function should be the last part of the c0 program");
			}else{
				syntaxError(token.getPos(), "\"void main(){...}\" is the right way to declare the main function");
			}
			
		}else{
			syntaxError(token.getPos(), "\"void main(){...}\" is the right way to declare the main function");
		}
		
	}

	/**
	 * Parameter			::= ‘（’ParamList‘)’
	 * ParamList			::=   int Identifier｛‘，’int Identifier} | NULL
	 * 
	 * 函数进入时token值		：LPAREN
	 * 函数退出时token值		：RPAREN的下一个记号,一定必须是LBRACKET，否则就会出现语法错误
	 * 
	 * @param funcSym		函数名字的符号表信息
	 */
	private void Parameter(FunctionSymbol funcSym){
		if(token.getToken() == LPAREN){
			token = scanner.nextToken();
			
			if(token.getToken() == RPAREN){
				token = scanner.nextToken();
				return;
			}
			
			if(token.getToken() == INT){
				token = scanner.nextToken();
				
				if(token.getToken() == IDENTIFIER){
					Symbol sym = NameTable.insertParam(funcSym.nameTable, token, log);
					funcSym.appendParam(sym);
					
					token = scanner.nextToken();
				}else{
					syntaxError(token.getPos(), "Wrong way to declare a parameter for a function with " + scanner.dumpToken(token));
					skipTo(COMMA);
				}
			}else{
				syntaxError(token.getPos(), "A parameter declaration must be start with 'int', not " + scanner.dumpToken(token));
				skipTo(COMMA);
			}
				
			while(token.getToken() == COMMA){
				token = scanner.nextToken();
				
				if(token.getToken() == INT)
					token = scanner.nextToken();
				else{
					syntaxError(token.getPos(), "A parameter declaration must be start with 'int', not " + scanner.dumpToken(token));
					skipTo(COMMA);
				}
				
				if(token.getToken() == IDENTIFIER){
					Symbol sym = NameTable.insertParam(funcSym.nameTable, token, log);
					funcSym.appendParam(sym);
						
					token = scanner.nextToken();
				}else{
					syntaxError(token.getPos(), "Wrong way to declare a parameter for a function with " + scanner.dumpToken(token));
					skipTo(COMMA);
				}
			}
				
			if(token.getToken() == RPAREN){
				token = scanner.nextToken();
			}else{
				syntaxError(token.getPos(), "Function " + funcSym.getName() + " define failed with " + scanner.dumpToken(token));
				skipTo(LBRACKET);
				
				//跳到函数程序块处或者下一个函数申明处
				while((token.getToken() == RBRACKET)
						||(token.getToken() == SEMI)){
					token = scanner.nextToken();
					skipTo(LBRACKET);
				}
				
				if(token.getToken() != LBRACKET)
					FuncHead();
			}
			
		}else{
			syntaxError(token.getPos(), "Function " + funcSym.getName() + " defined failed with " + scanner.dumpToken(token));
			skipTo(LBRACKET);
			
			//跳到函数程序块处或者下一个函数申明处
			while((token.getToken() == RBRACKET)
					||(token.getToken() == SEMI)){
				token = scanner.nextToken();
				skipTo(LBRACKET);
			}
			
			if(token.getToken() != LBRACKET)
				FuncHead();
				
		}
	}
	
	/**
	 * Block				::= ‘｛’［ConstantDec］［VarDec］StatementList‘｝’
	 * StatementList		::=  Statement｛Statement｝
	 * 
	 * 函数进入时token值		：LBRACKET
	 * 函数退出时token值		：RBRACKET下一个记号
	 *   
	 * @param table			程序块Block出现在函数定义后，table为此函数的符号表内容，也就是所有出现在Block内的所有变量和常量的局部符号表
	 * @param node			抽象语法树的块节点，也是所有出现在这个程序块内部的语句序列节点的父节点
	 */
	private void Block(NameTable table, BlockNode block){
		if(token.getToken() == LBRACKET){
			token = scanner.nextToken();
			
			if(token.getToken() == RBRACKET){
				token = scanner.nextToken();
				return;
			}else{
				
				if(token.getToken() == Tokens.CONST){			
					Constant(table);
				}
				
				if(token.getToken() == Tokens.INT){				
					VarDec(table);
				}
				
				StatementList(table, block);
				
				if(token.getToken() == RBRACKET)
					token = scanner.nextToken();
				else{
					syntaxError(token.getPos(), scanner.dumpToken(token));
					skip();//此处应该是skipTo(RBRACKET),但是RBRACKET是默认的终结符了
					
					//跳到下一个函数申明处
					while(token.getToken() == SEMI){
						token = scanner.nextToken();
						skipTo(RBRACKET);
					}
					
					if(token.getToken() == RBRACKET)
						token = scanner.nextToken();
				}
					
			}
			
		}else{
			syntaxError(token.getPos(), "Function defined failed with " + scanner.dumpToken(token));
			skipTo(LBRACKET);
			
			//跳到函数程序块处或者下一个函数申明处
			while((token.getToken() == RBRACKET)
					||(token.getToken() == SEMI)){
				token = scanner.nextToken();
				skipTo(LBRACKET);
			}
			
			if(token.getToken() != LBRACKET)
				FuncHead();
			else
				Block(table,block);
		}
	}
	
	/**
	 * StatementList		::=  Statement｛Statement｝
	 * 
	 * 函数进入时token值		：Statement()函数进入时的token值集合
	 * 函数退出时token值		：Statement()函数退出时的token值
	 *  
	 * @param table			程序块Block出现在函数定义后，table为此函数的符号表内容，也就是所有出现在Block内的所有变量和常量的局部符号表
	 * @param node			抽象语法树的块节点，也是所有出现在这个程序块内部的语句序列节点的父节点
	 */
	private void StatementList(NameTable table,BlockNode block){
		Node node; 
		
		node = Statement(table);
		while(node != null){
			block.insertNode(node);
			node = Statement(table);
		}
	}
	
	/**
	 *  Statement			::=  IfStatement 
	 * 							｜WhileStatement
	 * 							｜‘{’StatementList‘}’
	 * 							｜FuncCall';'
	 * 							｜EvaluateStatement
	 * 							｜ReturnStatement
	 * 							｜ReadStatement
	 * 							｜PrintStatement
	 *  						｜';'
	 * 
	 * 各个基本语句的语法前缀为：
	 * IfStatement			：IF
	 * WhileStatement		：WHILE
	 * ‘{’StatementList‘}’	：LBRACKET
	 * FuncCall				：IDENTIFIER LPAREN
	 * EvaluateStatement	：IDENTIFIER EQ
	 * ReturnStatement		：RETURN
	 * ReadStatement		：SCANF
	 * PrintStatement		：PRINTF
	 * ';'					：SEMI
	 * 
	 * 
	 * 函数进入时token值		：各个基本语句的语法前缀
	 * 函数退出时token值		：各个基本语句退出时的token值，一般为当前语句的结束符(SEMI或者RBRACKET)的下一个记号
	 * 
	 * @param table			程序块Block出现在函数定义后，table为此函数的符号表内容，也就是所有出现在Block内的所有变量和常量的局部符号表
	 * @return				处理的当前基本语句所获得的子节点，当子节点为NULL时表示此时处理的并不是一个语句
	 */
	private Node Statement(NameTable table){
		switch(token.getToken()){
		default:
			return null;
		case IF:
			return IfStatement(table);
		case ELSE:
			syntaxError(token.getPos(),"An 'else' is partered with  a 'if'");
			token = scanner.nextToken();
			return Statement(table);
		case WHILE:
			return WhileStatement(table);		
		case LBRACKET:
			BlockNode block = new BlockNode();
			
			token = scanner.nextToken();
			StatementList(table,block);
			
			if(token.getToken() == RBRACKET)
				token = scanner.nextToken();
			else{
				syntaxError(token.getPos(), scanner.dumpToken(token));
				skip();//此处应该是skipTo(RBRACKET),但是RBRACKET是默认的终结符了
				
				//跳到下一个函数申明处
				while(token.getToken() == SEMI){
					token = scanner.nextToken();
					skipTo(RBRACKET);
				}
				
				if(token.getToken() == RBRACKET)
					token = scanner.nextToken();
			}
			
			return block;
		case IDENTIFIER:
			/*
			 * 先看它是否被申明，如果没有则检查它是否是关键字拼写错误
			 */
			Symbol identSym = lookup(token,table);
			if(identSym != null){//语句中以标识符开头的仅有函数调用和变量赋值
				Token ident = token;
				
				token = scanner.nextToken();
				if(token.getToken() == LPAREN){
					//函数调用
					CallNode callNode =  FuncCall(ident.getPos(), identSym, table);
					
					if(token.getToken() == SEMI)
						token = scanner.nextToken();
					else{
						syntaxError(token.getPos(), "Missing ';' before " + scanner.dumpToken(token));
						skipToSEMI();
					}
					
					return callNode;
				}else if(token.getToken() == EQ){
					//变量赋值
					return EvaluateStatement(ident.getPos(), identSym, table);
				}else{
					syntaxError(ident.getPos(), "What do you want to do with this identifier '" + identSym.getName() + "'?");
					skipToSEMI();
					
					return Statement(table);
				}
				
			}else{//查看是否为关键字拼写错误
				String ident = (String)token.getValue();
				
				if(PString.liksKeywords(ident, "if")){
					log.error(token.getPos(), "The keyword 'if' is not correctly spelled");
					token = new Token(IF,null,token.getPos());
				}else if(PString.liksKeywords(ident, "else")){
					log.error(token.getPos(), "The keyword 'else' is not correctly spelled");
					token = new Token(ELSE,null,token.getPos());
				}else if(PString.liksKeywords(ident, "while")){
					log.error(token.getPos(), "The keyword 'while' is not correctly spelled");
					token = new Token(WHILE,null,token.getPos());
				}else if(PString.liksKeywords(ident, "return")){
					log.error(token.getPos(), "The keyword 'return' is not correctly spelled");
					token = new Token(RETURN,null,token.getPos());
				}else if(PString.liksKeywords(ident, "scanf")){
					log.error(token.getPos(), "The keyword 'scanf' is not correctly spelled");
					token = new Token(SCANF,null,token.getPos());
				}else if(PString.liksKeywords(ident, "printf")){
					log.error(token.getPos(), "The keyword 'printf' is not correctly spelled");
					token = new Token(PRINTF,null,token.getPos());
				}else{
					log.error(token.getPos(), "Syntax Error");
					token = scanner.nextToken();					
				}
				
				return Statement(table);
			}
			
		case RETURN:
			return ReturnStatement(table);
		case SCANF:
			return ReadStatement(table);
		case PRINTF:
			return PrintStatement(table);
		case SEMI:
			token = scanner.nextToken();
			return new Node(Nodes.NodesCount);
		}
		
	}
	
	/**
	 * IfStatement			::=   if‘（’Condition‘）’Statement［else Statement］
	 * 
	 * 函数进入时token值		：IF
	 * 函数退出时token值		：Statement()退出时的token值
	 * 
	 * @param table			程序块Block出现在函数定义后，table为此函数的符号表内容，也就是所有出现在Block内的所有变量和常量的局部符号表
	 * @return				返回处理当前If语句所获得的IfNode（抽象语法树的子节点）
	 */
	private IfNode IfStatement(NameTable table){
		BinaryNode condition;
		BlockNode execBlock = null;
		BlockNode elseBlock = null;
		Node node;
		
		token = scanner.nextToken();
		
		if(token.getToken() == LPAREN){
			token = scanner.nextToken();
			
			condition = Condition(table);
			
			if(token.getToken() == RPAREN){
				token = scanner.nextToken();
				node = Statement(table);
				if(node.getNode() != Nodes.NodesCount){
					if(node instanceof BlockNode)
						execBlock = (BlockNode)node;
					else{
						execBlock = new BlockNode();
						execBlock.insertNode(node);
					}
				}
				
				if(token.getToken() == ELSE){
					token = scanner.nextToken();
					node = Statement(table);
					if(node.getNode() != Nodes.NodesCount){
						if(node instanceof BlockNode)
							elseBlock = (BlockNode)node;
						else{
							elseBlock = new BlockNode();
							elseBlock.insertNode(node);
						}
					}
				}else{
					/*
					 * 希望没有谁会“走运”地用于“else”相近的单词来命名变量，而且是未申明就使用的，否则它也就只能一直地被编译不通过
					 */
					if(token.getToken() == IDENTIFIER){
						Symbol sym = lookup(token,table);
						
						if((sym == null)
								&&(PString.liksKeywords((String)token.getValue(), "else"))){
							log.error(token.getPos(), "The keyword 'else' is not correctly spelled");
							
							token = scanner.nextToken();							
							node = Statement(table);
							if(node.getNode() != Nodes.NodesCount){
								if(node instanceof BlockNode)
									elseBlock = (BlockNode)node;
								else{
									elseBlock = new BlockNode();
									elseBlock.insertNode(node);
								}
							}
						}
					}
				}		
				
				return new IfNode(condition,execBlock,elseBlock);
			}else{
				syntaxError(token.getPos(), "Condition Statement must be between '(' and ')'");
				skip();
				return new IfNode();
			}
			
		}else{
			syntaxError(token.getPos(), "Condition Statement must be between '(' and ')'");
			skip();
			return  new IfNode();
		}
	}
	
	/**
	 * WhileStatement		::=   while‘（’Condition‘）’Statement
	 * 
	 * 函数进入时token值		：WHILE
	 * 函数退出时token值		：Statement()退出时的token值
	 * 
	 * @param table			程序块Block出现在函数定义后，table为此函数的符号表内容，也就是所有出现在Block内的所有变量和常量的局部符号表
	 * @return				返回处理当前While语句所获得的WhileNode（抽象语法树的子节点）
	 */
	private WhileNode WhileStatement(NameTable table){
		BinaryNode condition;
		BlockNode execBlock = null;
		Node node;
		
		token = scanner.nextToken();
		if(token.getToken() == LPAREN){
			token = scanner.nextToken();
			condition = Condition(table);
			
			if(token.getToken() == RPAREN){
				token = scanner.nextToken();
				node = Statement(table);
				if(node.getNode() != Nodes.NodesCount){
					if(node instanceof BlockNode)
						execBlock = (BlockNode)node;
					else{
						execBlock = new BlockNode();
						execBlock.insertNode(node);
					}
				}
			}else{
				syntaxError(token.getPos(), "Condition Statement must be between '(' and ')'");
				skip();
				return  new WhileNode();
			}
			
			return new WhileNode(condition,execBlock);
		}else{
			syntaxError(token.getPos(), "Condition Statement must be between '(' and ')'");
			skip();
			return  new WhileNode();
		}
	}
	
	/**
	 * Condition			::=  Expression RelationOp Expression｜Expression
	 * RelationOp			::=   ＜｜＜＝｜＞｜＞＝｜!=｜==
	 * 
	 * 函数进入时token值		：Expression()进入时的token值集合
	 * 函数退出时token值		：Expression()退出时的token值
	 * 
	 * @param table			程序块Block出现在函数定义后，table为此函数的符号表内容，也就是所有出现在Block内的所有变量和常量的局部符号表
	 * @return				返回处理当前Condition条件语句时所获得的BinaryNode（抽象语法树的子节点，此处是IfNode和WhileNode的一部分）
	 */
	private BinaryNode Condition(NameTable table){
		BinaryNode left;
		BinaryNode right;
		BinaryNode node = null;
		int condPos = token.getPos();
		
		left = Expression(table);
		
		if(left == null){
			Error(condPos, "The condition shouldn't be empty!");
		}else{
			node = new BinaryNode();
			node.setLeft(left);
			
			int nodeKind = RelationOp();
			
			if(nodeKind < Nodes.NodesCount){
				node.setNode(nodeKind);
				token = scanner.nextToken();
				right = Expression(table);
			}else{
				/*
				 * 此时条件中只有一个表达式，采用C语言的默认条件，即：
				 * 	当此表达式的值为0时，	条件为假
				 * 	当此表达式的值不为0时，	条件为真
				 */
				node.setNode(Nodes.NEQ);
				right = new BinaryNode(Nodes.UNARY);
				right.setLeft(new LeafNode(Nodes.NUM, 0));
			}
			
			node.setRight(right);
			
		}
		
		return node;
	}
	
	/**
	 * FuncCall				::=  Identifier‘（’ValueList‘）’
	 * 直接后缀记号为‘；’
	 * 
	 * 函数进入时token值		：LPAREN
	 * 函数退出时token值		：RPAREN下一个记号
	 * 
	 * @param pos			函数调用的位置
	 * @param Symbol		被调用的函数的符号表信息
	 * @param table			程序块Block出现在函数定义后，table为此函数的符号表内容，也就是所有出现在Block内的所有变量和常量的局部符号表
	 * @return				返回处理当前函数调用语句时所获得的CallNode（抽象语法树的子节点）
	 */
	private CallNode FuncCall(int pos, Symbol sym, NameTable table){
		FunctionSymbol funcSym;
		CallNode callNode;
		
		/*
		 * 在这里假定函数在调用前一定需要申明才行
		 * 否则就必须采用在这里将被调用的函数形式保存在context中，在后面分析时碰到了申明在解除“误会”，
		 * 但是，如果整个语法分析器结束时context内仍有“误会”，则表示出现了错误！
		 */
		if(! Symbol.isFunc(sym)){
			Error(pos, "Identifier '" + sym.getName() + "' is not a function identifier!");
		}
		
		funcSym = (FunctionSymbol)sym;
		callNode = new CallNode(funcSym);
		
		token = scanner.nextToken();
		ValueList(table,callNode);
		
		if(token.getToken() == RPAREN){
			token = scanner.nextToken();
		}else{
			syntaxError(token.getPos(), "A function caller's value list must be between '(' and ')' ");
			skip();
		}
		
		if(funcSym != null){
			if(callNode.getParamCount() < funcSym.getParamCount())
				Error(pos, "'" + sym.getName() + "' :Too few arguments for call");
			else if(callNode.getParamCount() > funcSym.getParamCount())
				Error(pos, "'" + sym.getName() + "' :Too many arguments for call");
		}
		
		return callNode;
	}
	
	/**
	 * ValueList			::=  Expression｛，Expression｝｜NULL
	 * 
	 * 函数进入时token值		：Expression()进入时的token值集合 或者是 RPAREN
	 * 函数退出时token值		：RPAREN 或者是Expression()退出时的token值集合（一定必须是RPAREN，否则就是语法错误）
	 * 
	 * @param table			程序块Block出现在函数定义后，table为此函数的符号表内容，也就是所有出现在Block内的所有变量和常量的局部符号表
	 * @param father		抽象语法树中当前被调用函数的CallNode子节点，在这里是所有出现在这个值列表中的表达式返回节点的父节点
	 */
	private void  ValueList(NameTable table,CallNode father){
		BinaryNode expr;
		
		if(token.getToken() == RPAREN)
			return;
		expr = Expression(table);
		father.appendParam(expr);
		
		while(token.getToken() == COMMA){
			token = scanner.nextToken();
			expr = Expression(table);
			father.appendParam(expr);
		}
	}
	
	/**
	 * EvaluateStatement	::=  Identifier'＝'Expression';'
	 * 
	 * 函数进入时token值		：EQ
	 * 函数退出时token值		：SEMI的下一个记号
	 * 
	 * @param pos			赋值语句的位置
	 * @param identSym		‘=’记号左侧的被赋值的记号的符号表信息
	 * @param table			程序块Block出现在函数定义后，table为此函数的符号表内容，也就是所有出现在Block内的所有变量和常量的局部符号表
	 * @return				返回处理当前赋值语句时所获得的EvaluateNode（抽象语法树的子节点）
	 */
	private EvaluateNode EvaluateStatement(int pos, Symbol identSym, NameTable table){
		LeafNode ident;
		BinaryNode expr;
		int eqPos = token.getPos();
		
		if((! Symbol.isVar(identSym))
				&&(! Symbol.isParam(identSym)))
			Error(pos, "'=' : Left value specifies must be variable object");
		
		ident = new LeafNode(Nodes.VAR, identSym);
		
		token = scanner.nextToken();
		expr = Expression(table);
			
		if(expr == null)
			Error(eqPos, "'=' : Right Value shouldn't be empty!");
		
		if(token.getToken() == SEMI)
			token = scanner.nextToken();
		else{
			syntaxError(token.getPos(), scanner.dumpToken(token));
			skipToSEMI();
		}
			
		return new EvaluateNode(ident,expr);
	}

	/**
	 * ReturnStatement		::=  return [ ‘(’Expression‘)’]';'
	 * 						 	|return [ Expression ]';'
	 * 
	 * 函数进入时token值		：RETURN
	 * 函数退出时token值		：SEMI的下一个记号
	 * 
	 * 此处需要语义检查，是否返回值与函数返回值类型相同
	 * 
	 * @param table			程序块Block出现在函数定义后，table为此函数的符号表内容，也就是所有出现在Block内的所有变量和常量的局部符号表
	 * @return				返回处理当前函数返回语句时所获得的ReturnNode（抽象语法树的子节点）
	 */
	private ReturnNode ReturnStatement(NameTable table){
		BinaryNode expr;
		int retPos = token.getPos();
		/*
		 * 采用与ReadStatement()相同的“拒绝就走人”的递归下降方法
		 */
		token = scanner.nextToken();
		if(token.getToken() == SEMI){
			token = scanner.nextToken();
			return new ReturnNode();
		}
		
		if(token.getToken() == LPAREN){
			token = scanner.nextToken();
			expr = Expression(table);
			
			if(token.getToken() == RPAREN){
				token = scanner.nextToken();
			}else{
				syntaxError(token.getPos(), "Return Syntax: The expression should be between '(' and ')'");
				skipToSEMI();
				
				return new ReturnNode(expr, retPos);
			}
			
			if(token.getToken() == SEMI)
				token = scanner.nextToken();
			else{
				syntaxError(token.getPos(), "Missing ';' before " + scanner.dumpToken(token));
				skipToSEMI();
			}

			return new ReturnNode(expr, retPos);
		}else{
			int exprPos = token.getPos();
			expr = Expression(table);
			
			if(expr == null){
				syntaxError(exprPos, "Return Syntax: There should be an expression or null, not " + scanner.dumpToken(token));
			}else
				log.warn(exprPos, "Return Syntax: The expression should be between '(' and ')'");
			
			if(token.getToken() == SEMI)
				token = scanner.nextToken();
			else{
				syntaxError(token.getPos(), "Missing ';' before " + scanner.dumpToken(token));
				skipToSEMI();
			}
			
			return new ReturnNode(expr, retPos);
		}
	}

	/**
	 * ReadStatement		::=  scanf‘(’Identifier‘）’';'
	 * 
	 * 函数进入时token值		：SCANF
	 * 函数退出时token值		：SEMI的下一个记号
	 * 
	 * @param table			程序块Block出现在函数定义后，table为此函数的符号表内容，也就是所有出现在Block内的所有变量和常量的局部符号表
	 * @return				返回处理当前读语句时所获得的ScanNode（抽象语法树的子节点）
	 */
	private ScanNode ReadStatement(NameTable table){
		LeafNode varIdent = null;
		
		/*
		 * 不断的循环嵌套，让人头晕眼花，所以在这个函数内决定采用“拒绝就走人”的递归下降方法，让程序看起来不是那么乱
		 * 不过，前面的都已经写好了，等那天心情不好了，再来改吧
		 */
		token = scanner.nextToken();
		if(token.getToken() == LPAREN)
			token = scanner.nextToken();
		else{
			syntaxError(token.getPos(), scanner.dumpToken(token));
			skipToSEMI();
			
			return new ScanNode();
		}
		
		if(token.getToken() == IDENTIFIER){
			Symbol identSym = lookup(token, table);
			
			if((identSym != null) 
					&&(! Symbol.isVar(identSym))
					&&(! Symbol.isParam(identSym)))
				syntaxError(token.getPos(), "'scanf' : Value specifies must be variable object");
			
			varIdent = new LeafNode(Nodes.VAR,identSym);
			token = scanner.nextToken();
		}else{
			syntaxError(token.getPos(), "Value specifies is required for a scanf statement");
			skipToSEMI();
			
			return new ScanNode();
		}
			
		if(token.getToken() == RPAREN){
			token = scanner.nextToken();
		}else{
			syntaxError(token.getPos(), "Value specifies for the 'scanf' is required to between '(' and ')'");
			skipToSEMI();
			
			return new ScanNode(varIdent);
		}
		
		if(token.getToken() == SEMI)
			token = scanner.nextToken();
		else{
			syntaxError(token.getPos(), "Missing ';' before " + scanner.dumpToken(token));
			skipToSEMI();
		}
		
		return new ScanNode(varIdent);
	}

	/**
	 * PrintStatement		::=  printf‘(’String‘,’Expression|String|Expression‘）’';'
	 * String				::=   "｛<合法字符>}" //字符串中可以出现所有合法的可打印字符集中的字符
	 * 
	 * 函数进入时token值		：PRINTF
	 * 函数退出时token值		：SEMI的下一个记号
	 * 
	 * @param table			程序块Block出现在函数定义后，table为此函数的符号表内容，也就是所有出现在Block内的所有变量和常量的局部符号表
	 * @return				返回处理当前写语句时所获得的PrintNode（抽象语法树的子节点）
	 */
	private PrintNode PrintStatement(NameTable table){
		LeafNode str = null;
		BinaryNode expr = null;
		
		/*
		 * 采用和ReadStatement()里一样的“拒绝就走人”的递归下降方法
		 */
		token = scanner.nextToken();
		if(token.getToken() == LPAREN){
			token = scanner.nextToken();
		}else{
			syntaxError(token.getPos(), scanner.dumpToken(token));
			skipToSEMI();
			
			return new PrintNode();
		}
			
		if(token.getToken() == STRING){
			int index = globalTable.insertString((String)token.getValue());
			str = new LeafNode(Nodes.STRING,index);
			token = scanner.nextToken();
				
			if(token.getToken() == COMMA){
				token = scanner.nextToken();
				expr = Expression(table);
			}
				
			if(token.getToken() == RPAREN){
				token = scanner.nextToken();
			}else{
				syntaxError(token.getPos(), "Value specifies for the 'printf' is required to between '(' and ')'");
				skipToSEMI();
				
				return new PrintNode(str,expr);
			}
			
			if(token.getToken() == SEMI)
				token = scanner.nextToken();
			else{
				syntaxError(token.getPos(), "Missing ';' before " + scanner.dumpToken(token));
				skipToSEMI();
			}
			
			return new PrintNode(str,expr);
		}else{
			expr = Expression(table);
				
			if(expr == null){
				syntaxError(token.getPos(), "Value specifies is required for a printf statement");
				skipToSEMI();
				
				return new PrintNode();
			}else{
				if(token.getToken() == RPAREN){
					token = scanner.nextToken();
				}else{
					syntaxError(token.getPos(), "Value specifies for the 'printf' is required to between '(' and ')'");
					skipToSEMI();
					
					return new PrintNode(expr);
				}
			
				if(token.getToken() == SEMI)
					token = scanner.nextToken();
				else{
					syntaxError(token.getPos(), "Missing ';' before " + scanner.dumpToken(token));
					skipToSEMI();
				}
				
				return new PrintNode(expr);
			}
		}
	}
	
	/**
	 * Expression			::= ['＋'｜'－'］Term ｛PlusOp Term｝
	 * PlusOp				::= '+' | '－'
	 * 
	 * 函数进入时token值		：PLUS、SUB 或者 Term()进入时的token值集合
	 * 函数退出时token值		：Term()退出时的token值
	 * 
	 * @param table			程序块Block出现在函数定义后，table为此函数的符号表内容，也就是所有出现在Block内的所有变量和常量的局部符号表
	 * @return				返回处理当前表达式时所获得的BinaryNode（抽象语法树的子节点）
	 */
	private BinaryNode Expression(NameTable table){
		BinaryNode expr = null;
		BinaryNode term;
		int nodeKind = PlusOp();
		int overPos = 0;
		
		if(nodeKind < Nodes.NodesCount){
			overPos = token.getPos();
			token = scanner.nextToken();
			expr = new BinaryNode(nodeKind);
			BinaryNode left = new BinaryNode(Nodes.UNARY);
			left.setLeft(new LeafNode(Nodes.NUM,0));
			expr.setLeft(left);			
		}
		
		term = Term(table);
		
		if(term == null){
			if(expr != null)
				syntaxError(overPos,"What does it mean only by a plus operator character?");
			
			return null;
		}
		
		if(expr == null)
			expr = term;
		else
			expr.setRight(term);
		
		nodeKind = PlusOp();
		while(nodeKind  < Nodes.NodesCount){
			token = scanner.nextToken();
			term = Term(table);
			expr = new BinaryNode(nodeKind,expr,term);
			nodeKind = PlusOp();
		}
		
		return expr;
	}
	
	/**
	 * Term					::=   Factor {MultOp Factor}
	 * MultOp				::=   * ｜／
	 * 
	 * 函数进入时token值		：Factor()进入时的token值集合
	 * 函数退出时token值		：Factor()退出时的token值
	 * 
	 * @param table			程序块Block出现在函数定义后，table为此函数的符号表内容，也就是所有出现在Block内的所有变量和常量的局部符号表
	 * @return				返回处理当前项时所获得的BinaryNode（抽象语法树的子节点）
	 */
	private BinaryNode Term(NameTable table){
		BinaryNode term;
		BinaryNode factor;
		int nodeKind;
		
		term = Factor(table);
		nodeKind = MultOp();
		while(nodeKind < Nodes.NodesCount){
			token = scanner.nextToken();
			factor = Factor(table);
			term = new BinaryNode(nodeKind,term,factor);
			nodeKind = MultOp();
		}
		
		return term;
	}
	
	/**
	 * Factor				::=  Identifier ｜‘（’Expression‘）’｜Integer｜FuncCall
	 * 
	 * 函数进入时token值		：IDENTIFIER、LPAREN、NUM
	 * 函数退出时token值		：IDENTIFIER、RPAREN、NUM的下一个记号
	 * 
	 * @param table			程序块Block出现在函数定义后，table为此函数的符号表内容，也就是所有出现在Block内的所有变量和常量的局部符号表
	 * @return				返回处理当前因子时所获得的BinaryNode（抽象语法树的子节点）
	 */
	private BinaryNode Factor(NameTable table){
		BinaryNode factor = null;
		
		switch(token.getToken()){
		case LPAREN:
			token = scanner.nextToken();
			factor = Expression(table);
			
			if(token.getToken() == RPAREN){
				token = scanner.nextToken();
			}else{
				syntaxError(token.getPos(), "'(' should be parter with ')', not " + scanner.dumpToken(token));
				if((RelationOp() == Nodes.NodesCount)
						&&(PlusOp() == Nodes.NodesCount)
						&&(MultOp() == Nodes.NodesCount)){
					skipToSEMI();
				}
			}
			
			break;
		case PLUS:
			int overPos = token.getPos();
			
			token = scanner.nextToken();
			if(token.getToken() == NUM){
				factor = new BinaryNode(Nodes.UNARY);
				factor.setLeft(new LeafNode(Nodes.NUM,(Integer)token.getValue()));
				token = scanner.nextToken();
			}else
				syntaxError(overPos,"What does it mean only by a plus operator character?");
			
			break;
		case SUB:
			overPos = token.getPos();
			
			token = scanner.nextToken();
			if(token.getToken() == NUM){
				int num = (Integer)token.getValue();
				
				factor = new BinaryNode(Nodes.UNARY);
				factor.setLeft(new LeafNode(Nodes.NUM,0-num));
				token = scanner.nextToken();
			}else
				syntaxError(overPos,"What does it mean only by a minus operator character?");
			
			break;
		case NUM:
			factor = new BinaryNode(Nodes.UNARY);
			factor.setLeft(new LeafNode(Nodes.NUM,(Integer)token.getValue()));
			token = scanner.nextToken();
			break;
		case IDENTIFIER:
			Token ident = token;
			Symbol identSym = lookup(token,table);
			
			token = scanner.nextToken();
			if(identSym != null){//如果identSym为null则是变量未申明，不过这个在lookup()函数里已经有报错了
				if(token.getToken() == LPAREN){
					CallNode callNode = FuncCall(ident.getPos(), identSym, table);
					
					if(callNode.getFuncSym() != null){
						if(FunctionSymbol.isInt(callNode.getFuncSym())){
							factor = new BinaryNode(Nodes.UNARY);
							factor.setLeft(callNode);
						}else{
							Error(ident.getPos(), "Type Mistake: 'void' illegal with all types");
						}
					}
					break;
				}
				
				if(Symbol.isVar(identSym)
						|| Symbol.isParam(identSym)){
					factor = new BinaryNode(Nodes.UNARY);
					factor.setLeft(new LeafNode(Nodes.VAR, identSym));
				}else if(Symbol.isConstant(identSym)){
					ConstantSymbol conSym = (ConstantSymbol)identSym;
					factor = new BinaryNode(Nodes.UNARY);
					factor.setLeft(new LeafNode(Nodes.NUM, conSym.getValue()));
				}else if(Symbol.isFunc(identSym)){
					Error(ident.getPos(), "Wrong way to call a function");
				}else{
					Error(ident.getPos(), "Undefined variable identifier '" + token.getValue() + "'");
				}
			}else{
				skip();
			}
			
			break;
		default:
			syntaxError(token.getPos(), scanner.dumpToken(token));
			skipToSEMI();
			break;
		}
		
		return factor;
	}
	
	/**
	 * PlusOp				::= '+'｜'－'
	 * 
	 * @return				当前token与接口com.kang.c0c.tree.Nodes中所定义的操作符类型相一致的整数
	 */
	private int PlusOp(){		
		if(token.getToken() == PLUS)
			return Nodes.PLU;
		else if(token.getToken() == SUB)
			return Nodes.SUB;
		
		return Nodes.NodesCount;
	}
	
	/**
	 * MultOp				::=   * ｜／
	 * 
	 * @return				当前token与接口com.kang.c0c.tree.Nodes中所定义的操作符类型相一致的整数
	 */
	private int MultOp(){
		if(token.getToken() == STAR)
			return Nodes.MUL;
		else if(token.getToken() == SLASH)
			return Nodes.DIV;
		
		return Nodes.NodesCount;
	}
	
	/**
	 * RelationOp			::=   ＜｜＜＝｜＞｜＞＝｜!=｜==
	 * 
	 * @return				当前token与接口com.kang.c0c.tree.Nodes中所定义的操作符类型相一致的整数
	 */
	private int RelationOp(){		
		switch(token.getToken()){
			default:
				return Nodes.NodesCount;
			case LT:
				return Nodes.LT;
			case GT:
				return Nodes.GT;
			case LTEQ:
				return Nodes.LEQ;
			case GTEQ:
				return Nodes.GEQ;
			case EQEQ:
				return Nodes.EQU;
			case BANGEQ:
				return Nodes.NEQ;
		}
	}

	private Log log;
	private GlobalTable globalTable;
	private Scanner scanner;
	private Token token;
	private	Tree tree;
}
